package com.lagou.bean;

import com.lagou.service.SleepService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
 * @Author:丁成煜
 * create time:2021/4/30 13:50
 */
@Component
public class SleepComponent {
    @Reference
    private SleepService sleepService;

    //方法列表
    List<Supplier<String>> methodList;
    //创建一个固定数量的线程池
    ExecutorService executorService = Executors.newFixedThreadPool(10);
    // 通过静态方法创建ScheduledExecutorService的实例
    private static ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(4);


    boolean startFlag=false;
    //访问次数记录
    int count=0;
    //消费者开始启动的时间
    long startTime;

    /**
     * 开始并发调用
     */
    public void start(){
        //修改启动标示
        if(startFlag){
            return;
        }
        startFlag=true;
        startTime=System.currentTimeMillis();
        //初始化方法列表
        methodList = Arrays.asList(sleepService::methodA,sleepService::methodB,sleepService::methodC);
        //开始启动
        doStart();
        //进行记录
        record();
    }

    private void record() {
        //3.每5秒钟进行一次上报
        scheduledExecutorService.scheduleAtFixedRate(()->{
            long l = (System.currentTimeMillis() - startTime)/1000;
            System.out.println(l+"秒访问次数:"+count+",平均"+(l!=0?count/l:0)+"次/秒");
        },0,5, TimeUnit.SECONDS);
    }

    //真正进行启动
    private void doStart() {
        for(int i=0;i<10;i++){
            executorService.execute(this::run);
        }
    }

    //进行远程调用的方法
    private void run(){
        Random random = new Random();
        while (true){
            //随机获得方法并执行
            int i = random.nextInt(3);
            methodList.get(i).get();
            synchronized (this){
                //进行一次计数
                ++count;
        }
        }
    }


}
